package com.zzh.tools.utils;

import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;


import com.zzh.tools.define_throw.ParameterException;
import com.zzh.tools.system.ToolThrow;

import java.io.Serializable;
import java.util.Map;

/**
 * @author zhangzhihao
 * @email zhangzhihao@gongjiangren.net
 * @date 2020-07-23
 * @desc
 */
public class ToolBundle {

    public static final String PAGE_COMPARE = "page_compare";

    /**
     * 根据uripath创建bundle
     *
     * @param uriPath uri 的string
     * @return 返回的添加参数都是string类型
     */
    public static Bundle createBundle(String uriPath) {
        if (TextUtils.isEmpty(uriPath)) {
            return null;
        }
        String[] strs = uriPath.split("\\?");
        if (strs.length < 2) {
            return null;
        }
        String[] keyValues = strs[1].split("&");
        Bundle bundle = new Bundle();
        for (int i = 0; i < keyValues.length; i++) {
            String[] values = keyValues[i].split("=");
            if (values == null || values.length != 2) {
                throw new ParameterException();
            }
            bundle.putString(values[0], values[1]);
        }
        return bundle;
    }


    public static Bundle createBundle(Object... objects) {
        ToolThrow.isLengthEvenNumberThrow(objects);
        Bundle bundle = new Bundle();
        for (int i = 0; i < objects.length; i += 2) {
            String key = (String) objects[i];
            Object value = objects[i + 1];
            if (value instanceof Integer) {
                bundle.putInt(key, (int) value);
            } else if (value instanceof String) {
                bundle.putString(key, (String) value);
            } else if (value instanceof Parcelable) {
                bundle.putParcelable(key, (Parcelable) value);
            } else if (value instanceof Double) {
                bundle.putDouble(key, (Double) value);
            } else if (value instanceof Float) {
                bundle.putFloat(key, (Float) value);
            } else if (value instanceof Byte) {
                bundle.putByte(key, (Byte) value);
            } else if (value instanceof Short) {
                bundle.putShort(key, (Short) value);
            } else if (value instanceof Long) {
                bundle.putLong(key, (Long) value);
            } else if (value instanceof Serializable) {
                bundle.putSerializable(key, (Serializable) value);
            }
        }
        return bundle;
    }

    /**
     * 比对一组参数和上层参数有没有变化
     *
     * @param bundle
     * @param o
     * @return
     */
    public static boolean compareParameters(Bundle bundle, Object... o) {
        ToolThrow.isLengthEvenNumberThrow(o);
        ToolThrow.isNullObjectThrow(bundle);
        if (!bundle.containsKey(PAGE_COMPARE)) {
            return false;
        }
        Map<String, Object> map = (Map<String, Object>) bundle.getSerializable(PAGE_COMPARE);
        for (int i = 0; i < o.length; i += 2) {
            boolean status = compareParameter(map, (String) o[i], o[i + 1]);
            if (!status) {
                return false;
            }
        }
        return true;
    }

    public static boolean compareParameters(Map<String, Object> map, Object... o) {
        ToolThrow.isLengthEvenNumberThrow(o);
        ToolThrow.isNullObjectThrow(map);
        for (int i = 0; i < o.length; i += 2) {
            boolean status = compareParameter(map, (String) o[i], o[i + 1]);
            if (!status) {
                return false;
            }
        }
        return true;
    }

    /**
     * 比对一个参数和上层参数有没有变化
     *
     * @param bundle 传入的bundle
     * @param key    key值
     * @param value  值
     * @return
     */
    public static boolean compareParameter(Bundle bundle, String key, Object value) {
        ToolThrow.isNullObjectThrow(bundle);
        ToolThrow.isNullObjectThrow(key);
        ToolThrow.isNullObjectThrow(value);
        if (!bundle.containsKey(PAGE_COMPARE)) {
            return false;
        }
        Map<String, Object> map = (Map<String, Object>) bundle.getSerializable(PAGE_COMPARE);
        return compareParameter(map, key, value);
    }

    /**
     * 比对一个参数和上层参数有没有变化
     *
     * @param map   传入的map
     * @param key   key值
     * @param value 值
     * @return
     */
    public static boolean compareParameter(Map<String, Object> map, String key, Object value) {
        ToolThrow.isNullObjectThrow(map);
        ToolThrow.isNullObjectThrow(key);
        ToolThrow.isNullObjectThrow(value);
        if (!map.containsKey(key)) {
            return false;
        }
        Object obj = map.get(key);
        if (obj instanceof String) {
            if (value instanceof String) {
                return TextUtils.equals((String) obj, (String) value);
            }
            ToolLog.i("zzh", "类型不对 String");
            return false;
        } else if (obj instanceof Integer) {
            if (value instanceof Integer) {
                return obj == value;
            }
            ToolLog.i("zzh", "类型不对 Integer");
            return false;
        } else if (obj instanceof Double) {
            if (value instanceof Double) {
                return obj == value;
            }
            ToolLog.i("zzh", "类型不对 Double");
            return false;
        } else if (obj instanceof Float) {
            if (value instanceof Float) {
                return obj == value;
            }
            ToolLog.i("zzh", "类型不对 Float");
            return false;
        } else if (obj instanceof Character) {
            if (obj instanceof Character) {
                return obj == value;
            }
            ToolLog.i("zzh", "类型不对 Character");
            return false;
        } else if (obj instanceof Byte) {
            if (value instanceof Byte) {
                return true;
            }
            ToolLog.i("zzh", "类型不对 Byte");
            return false;
        } else if (obj instanceof Short) {
            if (value instanceof Short) {
                return true;
            }
            ToolLog.i("zzh", "类型不对 Short");
            return false;
        }
        return false;
    }

}
